package com.saturn.titan.core.datatable;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springside.modules.mapper.JsonMapper;

import com.google.common.collect.Lists;

/**
 * datatable 请求参数转换类
 * @author lwh
 *
 */
public class DatatableRequestArgumentsResolver implements
		HandlerMethodArgumentResolver {
	
	private static JsonMapper mapperNoEmpty = JsonMapper.nonEmptyMapper();
	
	private static Logger logger = LoggerFactory.getLogger(DatatableRequestArgumentsResolver.class);

	public boolean supportsParameter(MethodParameter parameter) {
		return parameter.hasParameterAnnotation(DatatableRequest.class);
	}

	public Object resolveArgument(MethodParameter parameter,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
			WebDataBinderFactory binderFactory) throws Exception {
		
		DatatableRequestBean<Object> bean = new DatatableRequestBean<Object>();
		
		DatatableRequest anno = parameter.getParameterAnnotation(DatatableRequest.class);
		Class<?> conditionType = anno.searchConditionClass();
		if(conditionType != Object.class && webRequest.getParameter("search[value]") != null && !webRequest.getParameter("search[value]").trim().equals("")){
			try {
				Object convert = mapperNoEmpty.fromJson(webRequest.getParameter("search[value]"), conditionType);
				bean.setSearchBean(convert);
			} catch (Exception e) {
				logger.warn("datatable convert condition json fail;");
			}
		}
		
		List<DatatableColumn> columns = Lists.newArrayList();
		
		DatatableColumn tmp = null;
		for(int i = 0 ; webRequest.getParameter("columns["+i+"][data]") != null ; i ++){
			tmp = new DatatableColumn();
			columns.add(tmp);
			tmp.data = webRequest.getParameter("columns["+i+"][data]");
			tmp.name= webRequest.getParameter("columns["+i+"][name]");
			tmp.orderable= webRequest.getParameter("columns["+i+"][orderable]")==null?null:Boolean.valueOf(webRequest.getParameter("columns["+i+"][orderable]"));
			tmp.search_regex= webRequest.getParameter("columns["+i+"][search][regex]");
			tmp.search_search= webRequest.getParameter("columns["+i+"][search][search]");
			tmp.searchable= webRequest.getParameter("columns["+i+"][searchable]")==null?null:Boolean.valueOf(webRequest.getParameter("columns["+i+"][searchable]"));
		}
		bean.setColumns(columns);
		
		List<DatatableOrder> orders = Lists.newArrayList();
		DatatableOrder tmpo = null;
		for(int i = 0 ; webRequest.getParameter("order["+i+"][column]") != null ; i ++){
			tmpo = new DatatableOrder();
			orders.add(tmpo);
			tmpo.column=webRequest.getParameter("order["+i+"][column]")==null?null:webRequest.getParameter("order["+i+"][column]");
			
			try {
				if(tmpo.column != null && columns.get(Integer.valueOf(tmpo.column)) != null){
					tmpo.column = columns.get(Integer.valueOf(tmpo.column)).name;
				}
			} catch (Exception e) {
			}
			
			tmpo.dir=webRequest.getParameter("order["+i+"][dir]");
		}
		bean.setOrder(orders);
		bean.setStart(webRequest.getParameter("start")==null?null:Integer.valueOf(webRequest.getParameter("start")));
		bean.setLength(webRequest.getParameter("length")==null?null:Integer.valueOf(webRequest.getParameter("length")));
		
		if(Integer.valueOf(-1).equals(bean.getLength())){
			bean.setLength(null);
			bean.setStart(null);
		}
		
		bean.setSearch_regex(webRequest.getParameter("search[regex]")==null?null:Boolean.valueOf(webRequest.getParameter("search[regex]")));
		bean.setSearch_value(webRequest.getParameter("search[value]"));
		bean.setRandom(webRequest.getParameter("_"));
		
		return bean;
	}

}
